#include "ManejadorLista.h"

using namespace Manejadores;

ManejadorLista::ManejadorLista() {
	Configuracion* config = config->getInstancia();
	string pathDeDatos = config->getNombreArchivoLista();
	this->listas = new ArchivoDeEstructurasVariables(pathDeDatos);
	this->indicePorUnicidad = new HashExtensible("IndicePorUnicidadLista");
	this->indicePorEleccion = new ArbolBMas("IndiceListaPorEleccion");
}

bool ManejadorLista::alta(Lista* lista) {
	string claveFecha = Utils::convertirEnteroAString(lista->getEleccion()->getFecha());
	string claveCargo = lista->getEleccion()->getCargo()->getNombre();
	string claveNombre = lista->getNombre();
	string clavePorUnicidad = claveFecha + claveCargo + claveNombre;
	if (!indicePorUnicidad->existe(clavePorUnicidad)) {
		unsigned int posicionDelRegistro = listas->insertar(lista);
		indicePorUnicidad->insertar(clavePorUnicidad, posicionDelRegistro);
		string clavePorEleccion = claveFecha + claveCargo;
		indicePorEleccion->insertar(clavePorEleccion, posicionDelRegistro);

		indicePorUnicidad->exportarTxt("indiceUnicidadLista");
		indicePorEleccion->exportar("IndiceListaPorEleccion");
		return true;
	} else
		return false;

}

bool ManejadorLista::baja(Lista* lista) {
	string claveFecha = Utils::convertirEnteroAString(lista->getEleccion()->getFecha());
	string claveCargo = lista->getEleccion()->getCargo()->getNombre();
	string claveNombre = lista->getNombre();
	string clavePorUnicidad = claveFecha + claveCargo + claveNombre;
	IRegistroIndice* aBorrar = indicePorUnicidad->buscar(clavePorUnicidad);

	if (aBorrar->getOffsets()->size() > 0) {
		listas->borrar(lista, aBorrar->getOffsets()->at(0));
		indicePorUnicidad->eliminar(clavePorUnicidad, aBorrar->getOffsets()->at(0));
		string clavePorEleccion = claveFecha + claveCargo;
		indicePorEleccion->suprimir(clavePorEleccion, aBorrar->getOffsets()->at(0));

		indicePorUnicidad->exportarTxt("indiceUnicidadLista");
		indicePorEleccion->exportar("IndiceListaPorEleccion");
		return true;
	} else
		return false;
}

bool ManejadorLista::modificacion(Lista* lista) {

	string claveFecha = Utils::convertirEnteroAString(lista->getEleccion()->getFecha());
	string claveCargo = lista->getEleccion()->getCargo()->getNombre();
	string claveNombre = lista->getNombre();
	string clavePorUnicidad = claveFecha + claveCargo + claveNombre;

	IRegistroIndice* viejaPosicion = indicePorUnicidad->buscar(lista->getNombre());
	unsigned int nuevaPosicion = listas->modificar(lista, viejaPosicion->getOffsets()->at(0));

	if (viejaPosicion->getOffsets()->at(0) != nuevaPosicion) {

		string clavePorEleccion = claveFecha + claveCargo;
		indicePorUnicidad->modificar(lista->getNombre(), viejaPosicion->getOffsets()->at(0), nuevaPosicion);
		indicePorEleccion->modificar(clavePorEleccion, viejaPosicion->getOffsets()->at(0), nuevaPosicion);
		return true;
	} else
		return false;
}

Lista* ManejadorLista::recuperar(int fecha, string nombreCargo, string nombreLista) {
	string claveFecha = Utils::convertirEnteroAString(fecha);
	string clavePorUnicidad = claveFecha + nombreCargo + nombreLista;
	IRegistroIndice* registro = this->indicePorUnicidad->buscar(clavePorUnicidad);
	if (registro->getOffsets()->size() > 0) {
		Lista* lista = new Lista();
		this->listas->leer(lista, registro->getOffsets()->at(0));
		delete registro;
		return lista;
	} else {
		delete registro;
		return NULL;
	}
}

bool ManejadorLista::existe(int fecha, string nombreCargo, string nombreLista) {
	string clave = Utils::convertirEnteroAString(fecha) + nombreCargo + nombreLista;
	return this->indicePorUnicidad->existe(clave);
}

vector<Lista*>* ManejadorLista::recuperarListasPorFechaYCargo(int fecha, string nombreCargo) {
	string claveFecha = Utils::convertirEnteroAString(fecha);
	string clave = claveFecha + nombreCargo;
	IRegistroIndice* registro = this->indicePorEleccion->buscar(clave);
	vector<Lista*>* listas = new vector<Lista*> ;
	if (registro != NULL && clave == registro->getClave()) {
		for (unsigned int i = 0; i < registro->getOffsets()->size(); i++) {
			Lista* nuevaLista = new Lista();
			this->listas->leer(nuevaLista, registro->getOffsets()->at(i));
			listas->push_back(nuevaLista);
		}
		delete registro;
	}
	return listas;
}

bool ManejadorLista::listarTodos(){
	bool toReturn = false;
	fstream txtFile;
	Configuracion* config = Configuracion::getInstancia();
	string path = config->getPathReportes() + "ListadoListas.txt";
	txtFile.open(path.c_str(), ios::out);
	if (txtFile.bad()) {
		txtFile.open(path.c_str(), ios::out);
	}
	txtFile << "Lista			Fecha Elección		Cargo" << endl;
	txtFile << "=================================================================" << endl;

	vector<unsigned int>* offsets = this->indicePorUnicidad->getTodosLosDatos();
	if(!offsets->empty()){
		Lista* lista = new Lista();
		for (unsigned int i = 0; i < offsets->size(); ++i) {
			this->listas->leer(lista, offsets->at(i));
			txtFile  << lista->getNombre() << "			"
					 << lista->getEleccion()->getFecha() << "		"
					 << lista->getEleccion()->getCargo()->getNombre() << endl;

		}
		delete lista;
		toReturn = true;
		}else{
			toReturn = false;
		}
		txtFile.close();
		return toReturn;
}

ManejadorLista::~ManejadorLista() {
	delete this->listas;
	delete this->indicePorUnicidad;
	delete this->indicePorEleccion;
}
